package com.baichuan.zntx.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baichuan.common.core.domain.model.LoginUser;
import com.baichuan.common.core.utils.DateUtils;
import com.baichuan.common.core.utils.StringUtils;
import com.baichuan.common.redis.utils.CacheUtils;
import com.baichuan.common.satoken.utils.LoginHelper;
import com.baichuan.common.translation.annotation.Translation;
import com.baichuan.common.websocket.utils.WebSocketUtils;
import com.baichuan.zntx.common.GPSUtils;
import com.baichuan.zntx.domain.*;
import com.baichuan.zntx.domain.bo.CommandBo;
import com.baichuan.zntx.domain.bo.DeviceHistoryBo;
import com.baichuan.zntx.domain.bo.MessageBo;
import com.baichuan.zntx.mapper.CommandMapper;
import com.baichuan.zntx.mapper.DeviceMapper;
import com.baichuan.zntx.mapper.RegionMapper;
import com.baichuan.zntx.mapper.RfidMapper;
import com.baichuan.zntx.service.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.asm.Advice;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.chrono.ChronoLocalDate;
import java.util.Objects;

@Service
@Slf4j
@RequiredArgsConstructor
public class MessageHandlerServiceImpl implements IMessageHandlerService {
    private final ICommandService commandService;
    private final IDeviceService deviceService;
    private final IDeviceHistoryService deviceHistoryService;
    private final ITaskService taskService;
    private final IMessageService messageService;
    private final RfidMapper rfidMapper;
    private final RegionMapper regionMapper;
    private ChannelHandlerContext context;
    private final DeviceRulesService deviceRulesService;
    @Override
    public void processMessage(ChannelHandlerContext context, BaseMessage message) {
        MessageEnum type = MessageEnum.getStructureEnum(message);
        this.context = context;
        switch (Objects.requireNonNull(type)){
            case data -> {
                //处理数据消息
                processDataMsgByRule((DataMessage)message);
            }
            case rfid -> {
                //处理RFID消息
                processRfidMsg((RfidMessage) message);
            }
            case id -> {
                //处理ID设置消息
                processIdMsg((IdMessage) message);
            }
            case error -> {
                //处理错误消息
                processErrorMsg((DataMessage)message);
            }
        }
    }

    protected void processDataMsgByRule(DataMessage message){
        Device device = deviceService.queryBuDeviceId(message.getId());
        if(device == null){
            return;
        }
        //保存当前指令
        CommandBo command = new CommandBo();
        command.setDeviceId(device.getDeviceId());
        command.setIp(message.getIpAddress());
        command.setContent(message.getDataContent());
        command.setStatus(1);
        commandService.insertByBo(command);
        //历史状态保存
        DeviceHistoryBo history =  Convert.convert(DeviceHistoryBo.class, device);
        if(ObjectUtil.isNotNull(history)){
            history.setId(null);
            history.setCreateBy(null);
            history.setUpdateBy(null);
            history.setCreateTime(null);
            history.setUpdateTime(null);
            deviceHistoryService.insertByBo(history);
        }

        //修改设备状态
        device.setTrack(message.isHasTrack());
        device.setWheel(message.isHasWheel());
        //修改设备状态
        device.setEnergy(Double.parseDouble(message.getBattery()));
        device.setGpsStatus(message.isIslLocationValid()?1:0);
        if(message.isIslLocationValid()){
            device.setLatitude(message.getLocation().getLatitude());
            device.setLongtitude(message.getLocation().getLongitude());
        }
        device.setPosX(message.getPosition().getX());
        device.setPosY(message.getPosition().getY());
        device.setPosZ(message.getPosition().getZ());
        device.setHasRfid(message.isHasRfid());
        //调度任务查询及处理
        Task task = taskService.queryByDevice(device.getDeviceId());
        if(task!=null && task.getStatus() != 2){
            if(task.getTaskType() == 0){
                if(task.getStatus()==0 && !message.isHasRfid()){
                    device.setStatus(0);
                    task.setStatus(1);
                    task.setStartTime(LocalDateTime.now());
                }
                if(task.getStatus()==1 && message.isHasTrack() && message.isHasWheel()){
                    device.setStatus(0);
                    task.setStatus(2);
                    task.setExcuteTime(LocalDateTime.now());
                }
            }else{
                //同时检测不到铁轨和车轮 认为已经拆除
                if(task.getStatus()==0 && !message.isHasTrack() && !message.isHasWheel()){
                    device.setStatus(8);
                    task.setStatus(1);
                    task.setStartTime(LocalDateTime.now());
                }
                //检测到Rfid 认为已回库
                if(task.getStatus()==1 && message.isHasRfid()){
                    device.setStatus(8);
                    task.setStatus(2);
                    task.setExcuteTime(LocalDateTime.now());
                }
            }
            taskService.updateById(task);
        }

        deviceService.update(device);
        Region region = regionMapper.selectById(device.getRegion());
        //调用规则引擎判断
        deviceRulesService.evaluateDevice(device, region, task);
    }

    private void processRfidMsg(RfidMessage message){
        //rfid设置成功
    }
    private void processIdMsg(IdMessage message){
        //id设置成功
    }
    private void processErrorMsg(DataMessage message){
        //异常信息处理
    }
}
